import {Box} from 'grid-emotion';
import PropTypes from 'prop-types';
import React from 'react';
import styled from 'react-emotion';

import {PanelItem} from 'app/components/panels';
import {t, tct} from 'app/locale';
import Avatar from 'app/components/avatar';
import Button from 'app/components/button';
import Confirm from 'app/components/confirm';
import InlineSvg from 'app/components/inlineSvg';
import Link from 'app/components/links/link';
import LoadingIndicator from 'app/components/loadingIndicator';
import SentryTypes from 'app/sentryTypes';
import Tooltip from 'app/components/tooltip';
import recreateRoute from 'app/utils/recreateRoute';

const UserName = styled(Link)`
  font-size: 16px;
`;

const Email = styled('div')`
  color: ${p => p.theme.gray3};
  font-size: 14px;
`;

export default class OrganizationMemberRow extends React.PureComponent {
  static propTypes = {
    routes: PropTypes.array,
    // XXX: Spreading this does not work :(
    member: SentryTypes.Member,
    onRemove: PropTypes.func.isRequired,
    onLeave: PropTypes.func.isRequired,
    onSendInvite: PropTypes.func.isRequired,
    orgName: PropTypes.string.isRequired,
    memberCanLeave: PropTypes.bool,
    requireLink: PropTypes.bool,
    canRemoveMembers: PropTypes.bool,
    canAddMembers: PropTypes.bool,
    currentUser: SentryTypes.User,
    status: PropTypes.oneOf(['', 'loading', 'success', 'error']),
  };

  constructor(...args) {
    super(...args);
    this.state = {busy: false};
  }

  handleRemove = e => {
    const {onRemove} = this.props;

    if (typeof onRemove !== 'function') {
      return;
    }

    this.setState({busy: true});
    onRemove(this.props.member, e);
  };

  handleLeave = e => {
    const {onLeave} = this.props;

    if (typeof onLeave !== 'function') {
      return;
    }

    this.setState({busy: true});
    onLeave(this.props.member, e);
  };

  handleSendInvite = e => {
    const {onSendInvite} = this.props;

    if (typeof onSendInvite !== 'function') {
      return;
    }

    onSendInvite(this.props.member, e);
  };

  render() {
    const {
      params,
      routes,
      member,
      orgName,
      status,
      requireLink,
      memberCanLeave,
      currentUser,
      canRemoveMembers,
      canAddMembers,
    } = this.props;

    const {id, flags, email, name, roleName, pending, expired, user} = member;

    // if member is not the only owner, they can leave
    const needsSso = !flags['sso:linked'] && requireLink;
    const isCurrentUser = currentUser.email === email;
    const showRemoveButton = !isCurrentUser;
    const showLeaveButton = isCurrentUser;
    const canRemoveMember = canRemoveMembers && !isCurrentUser;
    // member has a `user` property if they are registered with sentry
    // i.e. has accepted an invite to join org
    const has2fa = user && user.has2fa;
    const detailsUrl = recreateRoute(id, {routes, params});
    const isInviteSuccessful = status === 'success';
    const isInviting = status === 'loading';
    const canResend = !expired && canAddMembers && (pending || needsSso);

    return (
      <PanelItem align="center" p={0} py={2}>
        <Box pl={2}>
          <Avatar size={32} user={user ? user : {id: email, email}} />
        </Box>

        <Box pl={1} pr={2} flex="1">
          <h5 style={{margin: '0 0 3px'}}>
            <UserName to={detailsUrl}>{name}</UserName>
          </h5>
          <Email>{email}</Email>
        </Box>

        <Box px={2} w={180}>
          {needsSso || pending ? (
            <div>
              <div>
                {expired ? (
                  <strong>{t('Expired')}</strong>
                ) : pending ? (
                  <strong>{t('Invited')}</strong>
                ) : (
                  <strong>{t('Missing SSO Link')}</strong>
                )}
              </div>

              {isInviting && (
                <div style={{padding: '4px 0 3px'}}>
                  <LoadingIndicator mini />
                </div>
              )}
              {isInviteSuccessful && <span>Sent!</span>}
              {!isInviting && !isInviteSuccessful && canResend && (
                <ResendInviteButton
                  priority="primary"
                  size="xsmall"
                  onClick={this.handleSendInvite}
                  data-test-id="resend-invite"
                >
                  {t('Resend invite')}
                </ResendInviteButton>
              )}
            </div>
          ) : (
            <div>
              {!has2fa ? (
                <Tooltip title={t('Two-factor auth not enabled')}>
                  <NoTwoFactorIcon />
                </Tooltip>
              ) : (
                <HasTwoFactorIcon />
              )}
            </div>
          )}
        </Box>

        <Box px={2} w={140}>
          {roleName}
        </Box>

        {showRemoveButton || showLeaveButton ? (
          <Box px={2} w={140}>
            {showRemoveButton && canRemoveMember && (
              <Confirm
                message={tct('Are you sure you want to remove [name] from [orgName]?', {
                  name,
                  orgName,
                })}
                onConfirm={this.handleRemove}
                onSuccess={tct('Removed [name] from [orgName]', {
                  name,
                  orgName,
                })}
                onError={tct('Error removing [name] from [orgName]', {
                  name,
                  orgName,
                })}
              >
                <Button icon="icon-circle-subtract" size="small" busy={this.state.busy}>
                  {t('Remove')}
                </Button>
              </Confirm>
            )}

            {showRemoveButton && !canRemoveMember && (
              <Button
                disabled
                size="small"
                title={t('You do not have access to remove members')}
                icon="icon-circle-subtract"
              >
                {t('Remove')}
              </Button>
            )}

            {showLeaveButton && memberCanLeave && (
              <Confirm
                message={tct('Are you sure you want to leave [orgName]?', {
                  orgName,
                })}
                onConfirm={this.handleLeave}
                onSuccess={tct('Left [orgName]', {
                  orgName,
                })}
                onError={tct('Error leaving [orgName]', {
                  orgName,
                })}
              >
                <Button priority="danger" size="small" icon="icon-exit">
                  {t('Leave')}
                </Button>
              </Confirm>
            )}

            {showLeaveButton && !memberCanLeave && (
              <Button
                size="small"
                icon="icon-exit"
                disabled
                title={t(
                  'You cannot leave this organization as you are the only organization owner.'
                )}
              >
                {t('Leave')}
              </Button>
            )}
          </Box>
        ) : null}
      </PanelItem>
    );
  }
}

const NoTwoFactorIcon = styled(props => (
  <InlineSvg {...props} src="icon-circle-exclamation" />
))`
  color: ${p => p.theme.error};
  font-size: 18px;
`;
const HasTwoFactorIcon = styled(props => (
  <InlineSvg {...props} src="icon-circle-check" />
))`
  color: ${p => p.theme.success};
  font-size: 18px;
`;

const ResendInviteButton = styled(Button)`
  padding: 0 4px;
  margin-top: 2px;
`;
